package com.tx.admin.noveldictdetail.service.impl;

import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.tx.admin.noveldict.pojo.dto.NovelDictListDTO;
import com.tx.admin.noveldict.pojo.po.NovelDict;
import com.tx.admin.noveldict.pojo.po.table.NovelDictTableDef;
import com.tx.admin.noveldict.pojo.vo.NovelDictVO;
import com.tx.admin.noveldict.service.NovelDictService;
import com.tx.admin.system.pojo.vo.sysuser.UserOptionVO;
import com.tx.core.util.*;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.tx.admin.noveldictdetail.service.NovelDictDetailService;
import com.tx.admin.noveldictdetail.pojo.po.NovelDictDetail;
import com.tx.admin.noveldictdetail.mapper.NovelDictDetailMapper;
import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.query.QueryChain;
import com.tx.core.common.enums.CommonResponseEnum;
import com.tx.core.common.entity.PageResult;
import com.tx.core.common.entity.SelectIdsDTO;
import java.io.Serializable;
import java.util.*;

import com.tx.admin.noveldictdetail.pojo.dto.NovelDictDetailCreateDTO;
import com.tx.admin.noveldictdetail.pojo.dto.NovelDictDetailUpdateDTO;
import com.tx.admin.noveldictdetail.pojo.dto.NovelDictDetailListDTO;
import com.tx.admin.noveldictdetail.pojo.dto.NovelDictDetailImportDTO;
import com.tx.core.common.entity.ImportExcelDTO;
import com.tx.excel.core.ExcelResult;
import java.io.OutputStream;
import java.util.function.Function;
import java.util.stream.Collectors;

import jakarta.servlet.http.HttpServletResponse;
import com.tx.excel.utils.ExcelUtils;
import lombok.SneakyThrows;
import com.tx.admin.noveldictdetail.pojo.vo.NovelDictDetailVO;

import static com.tx.admin.noveldict.pojo.po.table.NovelDictTableDef.NOVEL_DICT;
import static com.tx.admin.noveldictdetail.pojo.po.table.NovelDictDetailTableDef.NOVEL_DICT_DETAIL;
import static com.tx.admin.system.pojo.po.table.SysUserTableDef.SYS_USER;

/**
 * <p>
 * 字典详情 服务实现类
 * </p>
 *
 * @author sz-admin
 * @since 2025-05-06
 */
@Service
@RequiredArgsConstructor
public class NovelDictDetailServiceImpl extends ServiceImpl<NovelDictDetailMapper, NovelDictDetail> implements NovelDictDetailService {

    @Autowired
    @Lazy
    private NovelDictService novelDictService;

    @Override
    public void create(NovelDictDetailCreateDTO dto) {
        NovelDictDetail novelDictDetail = BeanCopyUtils.copy(dto, NovelDictDetail.class);
        save(novelDictDetail);
    }

    @Override
    public void update(NovelDictDetailUpdateDTO dto) {
        NovelDictDetail novelDictDetail = BeanCopyUtils.copy(dto, NovelDictDetail.class);
        QueryWrapper wrapper;
        // id有效性校验
        wrapper = QueryWrapper.create()
                .eq(NovelDictDetail::getId, dto.getId());
        CommonResponseEnum.INVALID_ID.assertTrue(count(wrapper) <= 0);

        saveOrUpdate(novelDictDetail);
    }

    @Override
    public PageResult<NovelDictDetailVO> page(NovelDictDetailListDTO dto) {
        Page<NovelDictDetailVO> page = pageAs(PageUtils.getPage(dto), buildQueryWrapper(dto), NovelDictDetailVO.class);
        return PageUtils.getPageResult(page);
    }

    @Override
    public List<NovelDictDetailVO> list(NovelDictDetailListDTO dto) {
        return listAs(buildQueryWrapper(dto), NovelDictDetailVO.class);
    }

    @Override
    public void remove(SelectIdsDTO dto) {
        CommonResponseEnum.INVALID_ID.assertTrue(dto.getIds().isEmpty());
        removeByIds(dto.getIds());
    }

    @Override
    public NovelDictDetailVO detail(Object id) {
        NovelDictDetail novelDictDetail = getById((Serializable) id);
        CommonResponseEnum.INVALID_ID.assertNull(novelDictDetail);
        return BeanCopyUtils.copy(novelDictDetail, NovelDictDetailVO.class);
    }

    @SneakyThrows
    @Override
    public void importExcel(ImportExcelDTO dto) {
        ExcelResult<NovelDictDetailImportDTO> excelResult = ExcelUtils.importExcel(dto.getFile().getInputStream(), NovelDictDetailImportDTO.class, true);
        List<NovelDictDetailImportDTO> list = excelResult.getList();
        List<String> errorList = excelResult.getErrorList();
        String analysis = excelResult.getAnalysis();
        System.out.println(" analysis : " + analysis);
        System.out.println(" isCover : " + dto.getIsCover());
    }

    @SneakyThrows
    @Override
    public void exportExcel(NovelDictDetailListDTO dto, HttpServletResponse response) {
        List<NovelDictDetailVO> list = list(dto);
        String fileName = "字典详情模板";
        OutputStream os = FileUtils.getOutputStream(response, fileName + ".xlsx");
        ExcelUtils.exportExcel(list, "字典详情", NovelDictDetailVO.class, os);
    }

    @Override
    public List<NovelDictDetailVO> getDetailsByCode(String code) {
        NovelDictListDTO select =new NovelDictListDTO();
        select.setCode(code);
        List<NovelDictVO> list = novelDictService.list(select);
        if (list.isEmpty()){
            throw new RuntimeException("存在该列表");
        }
        NovelDictDetailListDTO detailSelect =new NovelDictDetailListDTO();
        detailSelect.setDictId(list.get(0).getId());
        List<NovelDictDetailVO> list1 = this.list(detailSelect);

        return list1;
    }

    @Override
    public Map<String, List<NovelDictDetailVO>> getDetailOption() {
        QueryWrapper wrapper = QueryWrapper.create().select(NOVEL_DICT_DETAIL.ID,NOVEL_DICT_DETAIL.DICT_ID
        ,NOVEL_DICT_DETAIL.NAME,NOVEL_DICT_DETAIL.VALUE,NOVEL_DICT_DETAIL.NUM_KEY);
        List<NovelDictDetailVO> vos = listAs(wrapper, NovelDictDetailVO.class);
        Map<Long, NovelDictVO> idCodeMap = Optional.ofNullable(novelDictService.getDetailOption())
                .orElse(new ArrayList<>()).stream()
                .collect(Collectors.toMap(NovelDictVO::getId, Function.identity(), (o, n) -> o));

        Map<String, List<NovelDictDetailVO>> allDs = vos.stream().filter(s -> Objects.nonNull(s.getDictId())
                        && Objects.nonNull(s.getNumKey())).peek(s->{
                    NovelDictVO vo = idCodeMap.getOrDefault(s.getDictId(), new NovelDictVO());
                    s.setDictName(vo.getName());
                    s.setCode(vo.getCode());
                })
                .collect(Collectors.groupingBy(NovelDictDetailVO::getCode));

        return allDs;
    }

    private static QueryWrapper buildQueryWrapper(NovelDictDetailListDTO dto) {
        QueryWrapper wrapper = QueryWrapper.create().from(NovelDictDetail.class);
        if (Utils.isNotNull(dto.getDictId())) {
            wrapper.eq(NovelDictDetail::getDictId, dto.getDictId());
        }
        if (Utils.isNotNull(dto.getNumKey())) {
            wrapper.eq(NovelDictDetail::getNumKey, dto.getNumKey());
        }
        if (Utils.isNotNull(dto.getName())) {
            wrapper.like(NovelDictDetail::getName, dto.getName());
        }
        if (Utils.isNotNull(dto.getValue())) {
            wrapper.eq(NovelDictDetail::getValue, dto.getValue());
        }
        return wrapper;
    }
}